import { graphql } from 'gatsby';

import ARIA from '../../components/AriaAbbr';
import Callout from '../../components/Callout';
import ComponentApi from '../../components/ComponentApi';
import ReactPlayground from '../../components/ReactPlayground';
import DropdownBasic from '../../examples/Dropdown/Basic';
import DropdownBasicButton from '../../examples/Dropdown/BasicButton';
import DropdownButtonCustom from '../../examples/Dropdown/ButtonCustom';
import DropdownButtonCustomMenu from '../../examples/Dropdown/ButtonCustomMenu';
import DropdownButtonSizes from '../../examples/Dropdown/ButtonSizes';
import DropDirections from '../../examples/Dropdown/DropDirections';
import DropdownItemTags from '../../examples/Dropdown/DropdownItemTags';
import MenuAlignEnd from '../../examples/Dropdown/MenuAlignEnd';
import MenuAlignResponsive from '../../examples/Dropdown/MenuAlignResponsive';
import MenuDividers from '../../examples/Dropdown/MenuDividers';
import MenuHeaders from '../../examples/Dropdown/MenuHeaders';
import SplitBasic from '../../examples/Dropdown/SplitBasic';
import SplitVariants from '../../examples/Dropdown/SplitVariants';
import DropdownVariants from '../../examples/Dropdown/Variants';
import ButtonDark from '../../examples/Dropdown/ButtonDark';
import NavbarDark from '../../examples/Dropdown/NavbarDark';
import AutoClose from '../../examples/Dropdown/AutoClose';

import styles from '../../css/examples.module.scss';


# Dropdowns

<p className="lead">
  Toggle contextual overlays for displaying lists of links and more with
  the Bootstrap dropdown plugin
</p>

## Overview

Dropdowns are toggleable, contextual overlays for displaying lists of
links and more. Like overlays, Dropdowns are built using a third-party
library <a href="https://popper.js.org/">Popper.js</a>, which provides
dynamic positioning and viewport detection.


## Accessibility

The <a href="https://www.w3.org/TR/wai-aria/"><abbr title="Web Accessibility Initiative">WAI</abbr> <ARIA /></a> standard
defines a [`role="menu"` widget][1], but it's very specific to a certain kind of menu. <ARIA /> menus, must
only contain `role="menuitem"`, `role="menuitemcheckbox"`, or `role="menuitemradio"`.

On the other hand, Bootstrap's dropdowns are designed to more generic
and application in a variety of situations. For this reason we don't
automatically add the menu roles to the markup. We do implement some
basic keyboard navigation, and if you do provide the "menu" role,
react-bootstrap will do its best to ensure the focus management is
compliant with the <ARIA /> authoring guidelines for menus.

## Examples

### Single button dropdowns

The basic Dropdown is composed of a wrapping `Dropdown` and
inner `<DropdownMenu>`, and `<DropdownToggle>`. By
default the `<DropdownToggle>` will render a
`Button` component and accepts all the same props.

<ReactPlayground codeText={DropdownBasic} />

Since the above is such a common configuration react-bootstrap provides
the `<DropdownButton>` component to help reduce typing. Provide
a `title` prop and some `<DropdownItem>`s and you're
ready to go.


<ReactPlayground codeText={DropdownBasicButton} />

DropdownButton will forward Button props to the underlying Toggle
component

<ReactPlayground codeText={DropdownVariants} />

### Split button dropdowns

Similarly, You create a split dropdown by combining the Dropdown
components with another Button and a ButtonGroup.

<ReactPlayground codeText={SplitBasic} />


As with DropdownButton, `SplitButton` is provided as
convenience component.

<ReactPlayground codeText={SplitVariants} />

## Sizing

Dropdowns work with buttons of all sizes.

<ReactPlayground codeText={DropdownButtonSizes} />

## Dark dropdowns

Opt into darker dropdowns to match a dark navbar or custom style by adding 
`variant="dark"` onto an existing `DropdownMenu`. Alternatively, use
`menuVariant="dark"` when using the `DropdownButton` component.

<ReactPlayground codeText={ButtonDark} />

Using `menuVariant="dark"` in a `NavDropdown`:

<ReactPlayground codeText={NavbarDark} />

## Drop directions

Trigger dropdown menus above, below, left, or to the right of their
toggle elements, with the `drop` prop.

<ReactPlayground codeText={DropDirections} />

## Dropdown items

Historically dropdown menu contents had to be links, but that’s no
longer the case with v4. Now you can optionally use
`<button>` elements in your dropdowns instead of just `<a>`s.

You can also create non-interactive dropdown items with `<Dropdown.ItemText>`.
Feel free to style further with custom CSS or text utilities.

<ReactPlayground codeText={DropdownItemTags} />

## Menu alignment

By default, a dropdown menu is aligned to the left, but you can switch
it by passing `align="end"` to a `<Dropdown>`, `<DropdownButton>`, or `<SplitButton>`.

<ReactPlayground codeText={MenuAlignEnd} />

### Responsive alignment

If you want to use responsive menu alignment, pass an object containing a breakpoint to the 
`align` prop on the `<DropdownMenu>`, `<DropdownButton>`, or `<SplitButton>`. 
You can specify `start` or `end` for the various breakpoints.

<Callout theme="danger" title="Warning">
  Using responsive alignment will disable Popper usage so any dynamic positioning 
  features such as <code>flip</code> will not work.
</Callout>


<ReactPlayground codeText={MenuAlignResponsive} />

## Menu headers

Add a header to label sections of actions.

<ReactPlayground
  codeText={MenuHeaders}
  exampleClassName={styles.staticDropdownMenu}
/>

## Menu dividers

Separate groups of related menu items with a divider.

<ReactPlayground
  codeText={MenuDividers}
  exampleClassName={styles.staticDropdownMenu}
/>

## AutoClose

By default, the dropdown menu is closed when selecting a menu item or clicking outside of the
dropdown menu. This behaviour can be changed by using the `autoClose` property.

By default, `autoClose` is set to the default value `true` and behaves like expected. By choosing `false`, the dropdown
menu can only be toggled by clicking on the dropdown button. `inside` makes the dropdown disappear __only__
by choosing a menu item and `outside` closes the dropdown menu __only__ by clicking outside.

__Notice__ how the dropdown is toggled in each scenario by clicking on the button.

<ReactPlayground codeText={AutoClose} />

## Customization

If the default handling of the dropdown menu and toggle components
aren't to your liking, you can customize them, by using the more basic
`<Dropdown>` Component to explicitly specify the Toggle and
Menu components

<ReactPlayground
  codeText={DropdownButtonCustom}
  exampleClassName={styles.customDropdownMenu}
/>

### Custom Dropdown Components

For those that want to customize everything, you can forgo the included
Toggle and Menu components, and create your own. By providing custom
components to the `as` prop, you can control how each
component behaves. Custom toggle and menu components __must__ be able to accept refs.

<ReactPlayground codeText={DropdownButtonCustomMenu} />

## API

<ComponentApi metadata={props.data.DropdownButton} />

<ComponentApi metadata={props.data.SplitButton} />

<ComponentApi metadata={props.data.Dropdown} />

<ComponentApi metadata={props.data.DropdownToggle} exportedBy={props.data.Dropdown} />

<ComponentApi metadata={props.data.DropdownMenu} exportedBy={props.data.Dropdown} />

<ComponentApi metadata={props.data.DropdownItem} exportedBy={props.data.Dropdown} />
<ComponentApi metadata={props.data.DropdownHeader} exportedBy={props.data.Dropdown} />
<ComponentApi
metadata={props.data.DropdownDivider}
exportedBy={props.data.Dropdown}
/>


export const query = graphql`
  query DropdownMDXQuery {
    DropdownButton: componentMetadata(displayName: { eq: "DropdownButton" }) {
      displayName
      ...ComponentApi_metadata
    }
    SplitButton: componentMetadata(displayName: { eq: "SplitButton" }) {
      displayName
      ...ComponentApi_metadata
    }
    Dropdown: componentMetadata(displayName: { eq: "Dropdown" }) {
      displayName
      ...ComponentApi_metadata
    }
    DropdownToggle: componentMetadata(displayName: { eq: "DropdownToggle" }) {
      displayName
      ...ComponentApi_metadata
    }
    DropdownMenu: componentMetadata(displayName: { eq: "DropdownMenu" }) {
      displayName
      ...ComponentApi_metadata
    }
    DropdownItem: componentMetadata(displayName: { eq: "DropdownItem" }) {
      displayName
      ...ComponentApi_metadata
    }
    DropdownHeader: componentMetadata(displayName: { eq: "DropdownHeader" }) {
      displayName
      ...ComponentApi_metadata
    }
    DropdownDivider: componentMetadata(displayName: { eq: "DropdownDivider" }) {
      displayName
      ...ComponentApi_metadata
    }
  }
`;

[0]: https://www.w3.org/TR/wai-aria/
[1]: https://www.w3.org/TR/wai-aria-1.1/#menu
